﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Transactions;
using Ledict.ConditionExtract.Common;
using Ledict.ConditionExtract.DAL;
using Ledict.ConditionExtract.IBLL;
using Ledict.ConditionExtract.IDAL;
using Ledict.Utility.Frm;
using Ledict.Utility.Helper;
using Lucene.Net.Analysis.CJK;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Store;
using Version = Lucene.Net.Util.Version;

namespace Ledict.ConditionExtract.BLL
{
    /// <summary>
    ///     索引创建业务逻辑
    /// </summary>
    public class LuceneCreate : ILuceneCreate
    {
        #region 构造

        //DefusePrivacy defuseprivacy = new DefusePrivacy();

        //private LogHelper logHelper = LogFactory.GetLogger();

        //索引存放路径
        private static readonly string indexPath = Path.Combine(ConfigHelper.AppSettings("luceneRoot"));
        //static string indexPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Expressluceneindex\");
        internal static readonly DirectoryInfo IndexDir = new DirectoryInfo(indexPath);

        private static readonly CJKAnalyzer analyzer = new CJKAnalyzer(Version.LUCENE_30);
        private readonly Lazy<ICreateIndexDal> createIndexDal;

        public int ResultCount { get; set; }
        public ProcessShow ProcessShow { get; set; }

        private readonly ParagraphToSentenceBll paragraphtosentence = new ParagraphToSentenceBll();
        //NewIDBLL newid = new NewIDBLL();
        private IndexWriter writer;

        public List<string> HeadWords = new List<string>(); //多个案由
        public int MaxCount = 0;
        //public ProcessShow ProcessShow { get; set; } //进度显示更新 

        //public LuceneCreate(IServiceGetter serviceGetter)
        //{
        //    createIndexDal = new Lazy<ICreateIndexDal>(serviceGetter.Get<ICreateIndexDal>);
        //}

        #endregion

        #region 案由


        /// <summary>
        /// 开始建表述索引
        /// </summary>
        /// <param name="headWords">案由列表</param>
        /// <param name="isSentence">是否分句，默认只分段</param>
        public void CreateIndex(IList<string> headWords, bool isSentence)
        {
            //判断指定目录索引是否存在，存在，则进行增量索引，不存在，则创建索引
            var isCreate = !IndexReader.IndexExists(FSDirectory.Open(IndexDir));
            //isCreate 决定创建索引是增量还是删除后重新创建
            writer = new IndexWriter(FSDirectory.Open(IndexDir), analyzer, isCreate,
                IndexWriter.MaxFieldLength.UNLIMITED);

            try
            {
                //1.通过案由ID，查询出需要建立索引的数据（已经创建过索引的不再查询范围内）
                var casedt = createIndexDal.Value.GetIndex(headWords); //案例

                //2.统计本次写入文件的索引数目
                if (casedt.Rows.Count > 0)
                {
                    //using (var tran = new TransactionScope())
                    //{

                    #region 写索引

                    //3.建立索引字段
                    foreach (DataRow dr in casedt.Rows)
                    {
                        //3.1取该案例的所有逻辑段(120,140,150) todo by zhangpeng:120（正文当事人）是2016-12-16新需求，目的是跑完表述后方便查看
                        var paradt = createIndexDal.Value.GetParagraph(dr["CaseId"].ToString());
                        //3.2取出该案例ID关联的所有案由
                        var dtHeadWord = createIndexDal.Value.GetHeadWords(dr["CaseID"].ToString());
                        //循环案由
                        foreach (DataRow dp in paradt.Rows)
                        {
                            //逻辑段内容
                            var paragraphText = dp["ParagraphText"].ToString();
                            //逻辑段类型编号120，140，150
                            var paragraphTypeId = Convert.ToInt32(dp["ParagraphTypeId"].ToString());
                            //逻辑段ID
                            var paragraphId = dp["Id"].ToString();
                            //案例ID
                            var caseId = dp["CaseId"].ToString();

                            var fieldValue = dr["FieldValue"].ToString();

                            //分句
                            if (isSentence)
                            {
                                //3.3段分句，按照规则
                                var returnDic = paragraphtosentence.GetSentence(paragraphText, paragraphTypeId);

                                #region 句

                                foreach (var key in returnDic)
                                {
                                    var doc = new Document();
                                    //添加doc  
                                    doc.Add(new Field("SentenceId", Guid.NewGuid().ToString(), Field.Store.YES,
                                        Field.Index.NOT_ANALYZED));
                                    doc.Add(new Field("SentenceTime", DateTime.Now.ToString(), Field.Store.YES,
                                        Field.Index.NOT_ANALYZED));
                                    doc.Add(new Field("Sentence", key, Field.Store.YES, Field.Index.ANALYZED)); //句
                                    doc.Add(new Field("ParagraphTypeId", paragraphTypeId.ToString(), Field.Store.YES,
                                        Field.Index.NOT_ANALYZED)); //段150
                                    doc.Add(new Field("CaseId", dr["CaseID"].ToString(), Field.Store.YES,
                                        Field.Index.NOT_ANALYZED)); //caseid
                                    doc.Add(new Field("PropertyId", dr["PropertyId"].ToString(), Field.Store.NO,
                                        Field.Index.NOT_ANALYZED));
                                    doc.Add(new Field("JudicialProcedureId", dr["JudicialProcedureId"].ToString(),
                                        Field.Store.NO, Field.Index.NOT_ANALYZED));
                                    doc.Add(new Field("CourtId", dr["CourtId"].ToString(), Field.Store.NO,
                                        Field.Index.NOT_ANALYZED));

                                    //存储逻辑段ID todo by zhangpeng:2016-12-23 新需求，可以在跑完表述查看原案例逻辑段内容
                                    doc.Add(new Field("ParagraphId", paragraphId, Field.Store.YES,
                                        Field.Index.NOT_ANALYZED));

                                    doc.Add(new Field("FieldValue", fieldValue, Field.Store.YES,
                                        Field.Index.NOT_ANALYZED));

                                    //案由
                                    for (var k = 0; k < dtHeadWord.Rows.Count; k++)
                                    {
                                        doc.Add(new Field("AllParentID",
                                            dtHeadWord.Rows[k]["HW_AllParentIDs"].ToString(), Field.Store.NO,
                                            Field.Index.NOT_ANALYZED));
                                    }
                                    writer.AddDocument(doc);
                                }

                                #endregion
                            }
                            else  //不分句
                            {
                                #region 段
                                var doc = new Document();
                                //添加doc  
                                doc.Add(new Field("SentenceId", Guid.NewGuid().ToString(), Field.Store.YES,
                                    Field.Index.NOT_ANALYZED));
                                doc.Add(new Field("SentenceTime", DateTime.Now.ToString(), Field.Store.YES,
                                    Field.Index.NOT_ANALYZED));
                                doc.Add(new Field("Sentence", paragraphText, Field.Store.YES, Field.Index.ANALYZED)); //段
                                doc.Add(new Field("ParagraphTypeId", paragraphTypeId.ToString(), Field.Store.YES,
                                    Field.Index.NOT_ANALYZED)); //段150，140，120
                                doc.Add(new Field("CaseId", dr["CaseID"].ToString(), Field.Store.YES,
                                    Field.Index.NOT_ANALYZED)); //caseid
                                doc.Add(new Field("PropertyId", dr["PropertyId"].ToString(), Field.Store.NO,
                                    Field.Index.NOT_ANALYZED));
                                doc.Add(new Field("JudicialProcedureId", dr["JudicialProcedureId"].ToString(),
                                    Field.Store.NO, Field.Index.NOT_ANALYZED));
                                doc.Add(new Field("CourtId", dr["CourtId"].ToString(), Field.Store.NO,
                                    Field.Index.NOT_ANALYZED));
                                
                                //存储逻辑段ID todo by zhangpeng:2016-12-23 新需求，可以在跑完表述查看原案例逻辑段内容
                                doc.Add(new Field("ParagraphId", paragraphId, Field.Store.YES,
                                       Field.Index.NOT_ANALYZED));

                                doc.Add(new Field("FieldValue", fieldValue, Field.Store.YES,
                                        Field.Index.NOT_ANALYZED));
                                
                                //案由
                                for (var k = 0; k < dtHeadWord.Rows.Count; k++)
                                {
                                    doc.Add(new Field("AllParentID",
                                        dtHeadWord.Rows[k]["HW_AllParentIDs"].ToString(), Field.Store.NO,
                                        Field.Index.NOT_ANALYZED));
                                }
                                writer.AddDocument(doc);
                                #endregion
                            }


                        }
                        //更新创建索引状态
                        createIndexDal.Value.UpdateIndexStatus(int.Parse(dr["CaseId"].ToString()));
                        ResultCount++;
                        ProcessShow(MaxCount, ResultCount);
                    }

                    writer.Optimize();
                    writer.Commit();
                    writer.Dispose();
                    //tran.Complete();

                    #endregion

                    //}

                    if (ResultCount < MaxCount) //循环
                    {
                        CreateIndex(headWords, isSentence);
                    }
                    else //不循环
                    {
                        ResultCount = MaxCount + 1;
                        ProcessShow(MaxCount, ResultCount); //已完成
                        writer.Dispose();
                    }
                }
                else //不循环
                {
                    ResultCount = MaxCount + 1;
                    ProcessShow(MaxCount, ResultCount); //已完成
                    writer.Dispose();
                }
            }
            catch (Exception ex)
            {
                Log.ErrorLog(ex.Message);
            }
            finally
            {
                writer.Dispose();
            }
        }

        /// <summary>
        ///     统计总数
        /// </summary>
        /// <returns></returns>
        public int GetSumCount(IList<string> headWords)
        {
            MaxCount = createIndexDal.Value.GetSumCount(headWords);
            return MaxCount; //逻辑段数据
        }

        #endregion

        #region 案例

        /// <summary>
        ///     统计总数
        /// </summary>
        /// <returns></returns>
        public int GetCaseSumCount(int cateGoryId)
        {
            MaxCount = createIndexDal.Value.GetCaseSumCount(cateGoryId); //逻辑段数据
            return MaxCount;
        }

        /// <summary>
        ///     开始建表述索引(分句),通过案例
        /// </summary>
        public void CreateCaseIndex(int cateGoryId)
        {
            //判断指定目录索引是否存在，存在，则进行增量索引，不存在，则创建索引
            var isCreate = !IndexReader.IndexExists(FSDirectory.Open(IndexDir));
            //isCreate 决定创建索引是增量还是删除后重新创建
            writer = new IndexWriter(FSDirectory.Open(IndexDir), analyzer, isCreate,
                IndexWriter.MaxFieldLength.UNLIMITED);
            try
            {
                //需要建立索引的数据
                var casedt = createIndexDal.Value.GetCaseIndex(cateGoryId); //案例

                //统计本次写入文件的索引数目
                if (casedt.Rows.Count > 0)
                {
                    //using (var tran = new TransactionScope())
                    //{
                    #region 写索引

                    //建立索引字段
                    foreach (DataRow dr in casedt.Rows)
                    {
                        //3.1取该案例的所有逻辑段(140,150)
                        var paradt = createIndexDal.Value.GetParagraph(dr["CaseId"].ToString());
                        //3.2取出该案例ID关联的所有案由
                        var dtHeadWord = createIndexDal.Value.GetHeadWords(dr["CaseID"].ToString());
                        //循环案由
                        foreach (DataRow dp in paradt.Rows)
                        {
                            var paragraphText = dp["ParagraphText"].ToString();
                            var paragraphTypeId = Convert.ToInt32(dp["ParagraphTypeId"].ToString());
                            //3.3段分句，按照规则
                            var returnDic = paragraphtosentence.GetSentence(paragraphText, paragraphTypeId);

                            #region 句

                            foreach (var key in returnDic)
                            {
                                var doc = new Document();
                                //添加doc  
                                doc.Add(new Field("SentenceId", Guid.NewGuid().ToString(), Field.Store.YES,
                                    Field.Index.NOT_ANALYZED));
                                doc.Add(new Field("SentenceTime", DateTime.Now.ToString(), Field.Store.YES,
                                    Field.Index.NOT_ANALYZED));
                                doc.Add(new Field("Sentence", key, Field.Store.YES, Field.Index.ANALYZED)); //句
                                doc.Add(new Field("ParagraphTypeId", paragraphTypeId.ToString(), Field.Store.YES,
                                    Field.Index.NOT_ANALYZED)); //段150
                                doc.Add(new Field("CaseId", dr["CaseID"].ToString(), Field.Store.YES,
                                    Field.Index.NOT_ANALYZED)); //caseid
                                doc.Add(new Field("PropertyId", dr["PropertyId"].ToString(), Field.Store.NO,
                                    Field.Index.NOT_ANALYZED));
                                doc.Add(new Field("JudicialProcedureId", dr["JudicialProcedureId"].ToString(),
                                    Field.Store.NO, Field.Index.NOT_ANALYZED));
                                doc.Add(new Field("CourtId", dr["CourtId"].ToString(), Field.Store.NO,
                                    Field.Index.NOT_ANALYZED));
                                //案由
                                for (var k = 0; k < dtHeadWord.Rows.Count; k++)
                                {
                                    doc.Add(new Field("AllParentID",
                                        dtHeadWord.Rows[k]["HW_AllParentIDs"].ToString(), Field.Store.NO,
                                        Field.Index.NOT_ANALYZED));
                                }
                                writer.AddDocument(doc);
                            }

                            #endregion
                        }
                        //更新创建索引状态
                        createIndexDal.Value.UpdateIndexStatus(int.Parse(dr["CaseId"].ToString()));
                        ResultCount++;
                        ProcessShow(MaxCount, ResultCount);
                    }

                    writer.Optimize();
                    writer.Commit();
                    writer.Dispose();
                    //tran.Complete();

                    #endregion
                    //}

                    if (ResultCount < MaxCount) //循环
                    {
                        CreateCaseIndex(cateGoryId);
                    }
                    else //不循环
                    {
                        ResultCount = MaxCount + 1;
                        ProcessShow(MaxCount, ResultCount); //已完成
                        writer.Dispose();
                    }
                }
                else //不循环
                {
                    ResultCount = MaxCount + 1;
                    ProcessShow(MaxCount, ResultCount); //已完成
                    writer.Dispose();
                }
            }
            catch (Exception ex)
            {
                Log.ErrorLog(ex.Message);
            }
            finally
            {
                writer.Dispose();
            }
        }

        #endregion

        #region 注释

        //public void CreateIndex_People()
        //{
        //    try
        //    {
        //        //需要建立索引的数据

        //        DataTable Casedt = createIndex.GetIndex(HeadWords);//案例
        //        DataTable Paradt;
        //        DataTable dtHeadWord;
        //        string ParagraphText = "";
        //        int ParagraphTypeId = 0;
        //        List<string> returnDic = new List<string>();
        //        //统计本次写入文件的索引数目

        //        if (Casedt.Rows.Count > 0)
        //        {
        //            #region 写索引
        //            //建立索引字段
        //            foreach (DataRow dr in Casedt.Rows)
        //            {
        //                Paradt = createIndex.GetParagraph(dr["CaseId"].ToString());//逻辑段
        //                dtHeadWord = createIndex.GetHeadWords(dr["CaseID"].ToString());
        //                foreach (DataRow dp in Paradt.Rows)
        //                {
        //                    ParagraphText = dp["ParagraphText"].ToString().Replace("\r", "").Replace("\n", "");
        //                    ParagraphTypeId = Convert.ToInt32(dp["ParagraphTypeId"].ToString());
        //                    returnDic = paragraphtosentence.GetSentence(ParagraphText, ParagraphTypeId);//分句
        //                    #region 句
        //                    foreach (string key in returnDic)
        //                    {
        //                        Document doc = new Document();
        //                        //添加doc  
        //                        doc.Add(new Field("SentenceId", Guid.NewGuid().ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
        //                        doc.Add(new Field("SentenceTime", DateTime.Now.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
        //                        doc.Add(new Field("Sentence", key, Field.Store.YES, Field.Index.ANALYZED));   //句
        //                        doc.Add(new Field("ParagraphTypeId", ParagraphTypeId.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));//段150
        //                        doc.Add(new Field("CaseId", dr["CaseID"].ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); //caseid
        //                        doc.Add(new Field("PropertyId", dr["PropertyId"].ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED));
        //                        doc.Add(new Field("JudicialProcedureId", dr["JudicialProcedureId"].ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED));
        //                        doc.Add(new Field("CourtId", dr["CourtId"].ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED));
        //                        //案由
        //                        for (int k = 0; k < dtHeadWord.Rows.Count; k++)
        //                        {
        //                            doc.Add(new Field("AllParentID", dtHeadWord.Rows[k]["HW_AllParentIDs"].ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED));
        //                        }
        //                        writer.AddDocument(doc);
        //                    }
        //                    #endregion
        //                }

        //                createIndex.UpdateIndexStatus(int.Parse(dr["CaseId"].ToString()));
        //                ResultCount++;
        //                processShow(MaxCount, ResultCount);

        //            }

        //            writer.Optimize();
        //            writer.Commit();
        //            if (ResultCount < MaxCount)//循环
        //            { CreateIndex_People(); }
        //            else //不循环
        //            {
        //                ResultCount = MaxCount + 1;
        //                processShow(MaxCount, ResultCount);//已完成
        //                writer.Close();
        //            }
        //            #endregion
        //        }
        //        else  //不循环
        //        {
        //            ResultCount = MaxCount + 1;
        //            processShow(MaxCount, ResultCount);//已完成
        //            writer.Close();
        //        }


        //    }
        //    catch (Exception error)
        //    {

        //    }


        //}

        #endregion
    }
}